package ErrorPackage;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import plg.Token;
import tipoToken.Tipos;

/**
 * Clase para detectar los errores en los tokens
 *
 * @author PLG Grupo 6
 */
public class Error {

    private static String[] legalCharList = inicializaListaCaracLegales();
    private static final int IDENTIFIER_MAX_LENGHT = 40;

    /**
     * Recibe un string que contiene un mensaje de error y lo imprime en pantalla
     * @param error
     */
    public void reportError(String error)
    {
        System.out.println(error);
    }

    /**
     * Recibe un token y lo analiza en busca de errores. En caso de encontrar error, se cambia el tipo al token al error correspondiente
     * @param token
     */
    public static void errorCheck(Token token)
    {
        if(token.getTipoToken().dameTipo().equals(Tipos.IDENTIFICADOR))
            if(tokenIsTooLarge(token))//Si es identificador se mira si es demasiado largo
                token.setTipo(Tipos.ErrorIdentifierTooLarge);
        if(tokenIsInvalidString(token))//Si es un string se mira si esta bien construido
            token.setTipo(Tipos.ErrorInvalidString);
        else if(tokenIsInvalidIdentifier(token))//Se comprueba si el identificador esta bien construido
            token.setTipo(Tipos.ErrorInvalidIdentifier);
        else if(tokenHasIllegalChar(token))//Se busca si el token tiene caracteres ilegales
            token.setTipo(Tipos.ErrorIllegalChar);

    }

    /**
     * Devuelve true si el token recibido contiene un caracter ilegal y false en caso contrario
     * @param token
     * @return
     */
    public static boolean tokenHasIllegalChar(Token token)
    {
        boolean legal = false;
        String lexema = token.getLexema();
        //Recorre el lexema para ver si todos sus caracteres son legales
        for(int i = 0; i<lexema.length();i++)
        {
            for(int j = 0; j< legalCharList.length;j++)
                if(legalCharList[j].charAt(0) == lexema.charAt(i))//Warning
                    legal = true;
            if(legal == false)//Si legal es false, el carcater es ilegal
                return true;
            else
                legal = false;
        }
        return false;
    }

    /**
     * Devuelve true si el identificador es invalido
     * @param token
     * @return
     */
    public static boolean tokenIsInvalidIdentifier(Token token)
    {
        //Compilamos el patron
        //El patron: No puede empezar con digito o _
        Pattern patron = Pattern.compile("[1-9_].*");
        // creamos el Matcher a partir del patron, y la cadena como parametro
        Matcher encajador = patron.matcher(token.getLexema());
        return encajador.matches();//Si la cadena encaja con el patron true, en caso contrario false
    }

    /**
     * Devuelve true si el string solo tiene comilla de apertura y no de clausura
     * @param token
     * @return
     */
    public static boolean tokenIsInvalidString(Token token)
    {
        //Compilamos el patron
        //El patron: No puede empezar con " si no temina tambien con "
        Pattern patron = Pattern.compile("\".*");
        // creamos el Matcher a partir del patron, y la cadena como parametro
        Matcher encajador = patron.matcher(token.getLexema());
        return encajador.matches();//Si la cadena encaja con el patron true, en caso contrario false
    }

    /**
     * Devuelve true si el lexema del token supera el máximo de caracteres permitido, false en caso contrario
     * @param token
     * @return
     */
    public static boolean tokenIsTooLarge(Token token)
    {
        if(token.getLexema().length() > IDENTIFIER_MAX_LENGHT)
            return true;
        else
            return false;
    }

    /**
     * Genera un array de string que contiene los caracteres legales para los identificadores
     * @return
     */
    private static String[] inicializaListaCaracLegales()
    {
        // creamos el array con todos los caracteres ilegales
        return new String[]{"q","w","e","r","t","y","u","i","o","p","a",
                            "s","d","f","g","h","j","k","l","z","x","c",
                            "v","b","n","m",
                            "Q","W","E","R","T","Y","U","I","O","P","A",
                            "S","D","F","G","H","J","K","L","Z","X","C",
                            "V","B","N","M",
                            "1","2","3","4","5","6","7",
                            "8","9","0"};
    }
}
